package com.sany.taskmanager.ui.activity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;

import com.sany.taskmanager.R;
import com.sany.taskmanager.databinding.ActivityBaseBinding;
import com.sany.taskmanager.global.Key;
import com.sany.taskmanager.http.DataRepository;
import com.sany.taskmanager.http.IHttpCallBack;
import com.sany.taskmanager.http.viewmodel.TaskViewModel;
import com.sany.taskmanager.http.viewmodel.TaskViewModelFactory;
import com.sany.taskmanager.manager.AppManager;
import com.sany.taskmanager.ui.widget.LoadingDialog;
import com.sany.taskmanager.ui.widget.TipDialog;
import com.sany.taskmanager.util.ClickUtil;
import com.sany.taskmanager.util.PreferenceUtil;
import com.sany.taskmanager.util.ToastUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import io.reactivex.rxjava3.disposables.CompositeDisposable;

/**
 * Activity页面基类
 */
public abstract class BaseActivity<VB extends ViewBinding> extends AppCompatActivity {

    protected VB vBinding;
    public final CompositeDisposable compositeDisposable = new CompositeDisposable();
    public TaskViewModel taskViewModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppManager.getAppManager().addActivity(this);
        int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE;
        getWindow().getDecorView().setSystemUiVisibility(flags);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.color_111929));
        ActivityBaseBinding activityBaseBinding = ActivityBaseBinding.inflate(getLayoutInflater());
        setContentView(activityBaseBinding.getRoot());

        Type superclass = getClass().getGenericSuperclass();
        Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
        try {
            Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class);
            vBinding = (VB) method.invoke(null, getLayoutInflater());
            activityBaseBinding.flBase.addView(vBinding.getRoot());
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        taskViewModel = new ViewModelProvider(this, new TaskViewModelFactory(DataRepository.getInstance())).get(TaskViewModel.class);
        if (showUsername()) {
            activityBaseBinding.includeTitle.tvUsername.setVisibility(View.VISIBLE);
            activityBaseBinding.includeTitle.tvUsername.setOnClickListener(v -> ClickUtil.onClick(BaseActivity.this));
            activityBaseBinding.includeTitle.tvLogout.setVisibility(View.VISIBLE);
            // 设置工号
            String username = PreferenceUtil.getPreferences().getString(Key.SharedKey.USERNAME);
            activityBaseBinding.includeTitle.tvUsername.setText(String.format(getString(R.string.format_username), username));
            // 点击退出登录
            activityBaseBinding.includeTitle.tvLogout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showTipDialog(getString(R.string.tip_confirm_logout), new TipDialog.OnConfirmListener() {
                        @Override
                        public void onConfirm() {
                            logout();
                        }
                    });

                }
            });
        } else {
            activityBaseBinding.includeTitle.tvUsername.setVisibility(View.GONE);
            activityBaseBinding.includeTitle.tvLogout.setVisibility(View.GONE);
        }
        initData();
    }

    /**
     * 是否显示工号和退出按钮
     */
    protected boolean showUsername() {
        return true;
    }

    /**
     * 退出登录
     */
    private void logout() {
        taskViewModel.logout(new IHttpCallBack<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                PreferenceUtil.getPreferences().putBoolean(Key.SharedKey.IS_LOGIN, false);
                startActivity(new Intent(BaseActivity.this, LoginActivity.class));
                AppManager.getAppManager().finishAllActivity();
            }

            @Override
            public void onFailed(String message) {
                ToastUtil.showToast(BaseActivity.this, message);
            }
        });
    }

    protected abstract void initData();

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {  //把操作放在用户点击的时候
            View v = getCurrentFocus();      //得到当前页面的焦点,ps:有输入框的页面焦点一般会被输入框占据
            if (isShouldHideKeyboard(v, event)) { //判断用户点击的是否是输入框以外的区域
                hideKeyboard(v.getWindowToken());   //收起键盘
            }
        }
        return super.dispatchTouchEvent(event);
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {  //判断得到的焦点控件是否包含EditText
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],    //得到输入框在屏幕中上下左右的位置
                    top = l[1], bottom = top + v.getHeight(), right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right && event.getY() > top && event.getY() < bottom) {
                // 点击位置如果是EditText的区域，忽略它，不收起键盘。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略
        return false;
    }

    /**
     * 获取InputMethodManager，隐藏软键盘
     *
     * @param token
     */
    private void hideKeyboard(IBinder token) {
        if (token != null) {
            InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        AppManager.getAppManager().finishActivity(this);
        compositeDisposable.clear();
    }

    /**
     * 再次确认的弹框
     */
    public void showTipDialog(String content, TipDialog.OnConfirmListener onConfirmListener) {
        final TipDialog dialog = new TipDialog(this, content);
        if (onConfirmListener != null) {
            dialog.setOnConfirmListener(onConfirmListener);
        }
        dialog.show();
    }

    private LoadingDialog mLoadingDialog;

    /**
     * 显示Loading加载框
     */
    public void showLoading() {
        if (mLoadingDialog == null) {
            mLoadingDialog = new LoadingDialog(this);
        }
        if (!mLoadingDialog.isShowing()) {
            mLoadingDialog.show();
        }
    }

    /**
     * 隐藏Loading加载框
     */
    public void hideLoading() {
        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
            mLoadingDialog.cancel();
        }
    }
}
